package com.pan.admin.module.loanProduct.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.MapUtils;
import com.pan.admin.common.annotation.DataScope;
import com.pan.admin.framework.web.service.PermissionService;
import com.pan.admin.module.loanProduct.entity.vo.LoanProductHistoryBillVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.gitee.apanlh.util.valid.ValidParam;
import com.pan.admin.module.loanProduct.dao.LoanProductHistoryBillDao;
import com.pan.admin.module.loanProduct.entity.qo.LoanProductHistoryBillQO;
import com.pan.admin.module.loanProduct.entity.vo.LoanProductBillVO;
import com.pan.admin.module.loanProduct.enums.BillTypeEnum;
import com.pan.admin.module.loanProduct.service.LoanProductHistoryBillService;

@Service
public class LoanProductHistoryBillServiceImpl implements LoanProductHistoryBillService {

    @Autowired
    private LoanProductHistoryBillDao loanProductHistoryBillDao;
    @Autowired
    private PermissionService permissionService;

    @Override
    @Transactional(readOnly = true)
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<LoanProductHistoryBillVO> listWithDataScope(LoanProductHistoryBillQO loanProductHistoryBillQO, String displayDateTime) {
        // 计划
        List<LoanProductHistoryBillVO> listLoanProductPlanList = this.loanProductHistoryBillDao
                .listLoanProductPlanWithDataScope(loanProductHistoryBillQO);

        //  结余
        List<LoanProductHistoryBillVO> loanProductHistoryBillVOS = this.loanProductHistoryBillDao
                .listLoanProductSurplusBill(loanProductHistoryBillQO);

        // 账单
        List<LoanProductBillVO> listLoanProductBill = this.loanProductHistoryBillDao
                .listLoanProductBill(loanProductHistoryBillQO);

        // 渠道总消耗
        List<LoanProductHistoryBillVO> listApiTotalConsumption = this.loanProductHistoryBillDao
                .listApiTotalConsumption(loanProductHistoryBillQO);

        Map<Long, BigDecimal> apiConsumeMap = listApiTotalConsumption.stream()
                .collect(Collectors.toMap(LoanProductHistoryBillVO::getLoanProductId, LoanProductHistoryBillVO::getAmount));

        // 充值
        Map<Long, BigDecimal> rechargeMap = listLoanProductBill.stream()
                .filter(item -> Eq.object(item.getType(), BillTypeEnum.RECHARGE.getValue()))
                .collect(Collectors.toMap(LoanProductBillVO::getLoanProductId, LoanProductBillVO::getAmount));
        // 补单
        Map<Long, BigDecimal> supplementMap = listLoanProductBill.stream()
                .filter(item -> Eq.object(item.getType(), BillTypeEnum.SUPPLEMENT.getValue()))
                .collect(Collectors.toMap(LoanProductBillVO::getLoanProductId, LoanProductBillVO::getAmount));

        // 将结余数据按 loanProductId 存储在 Map 中
        Map<Long, BigDecimal> surplusMap = loanProductHistoryBillVOS.stream()
                .filter(loanProduct -> loanProduct.getLoanProductId() != null)
                .filter(loanProduct -> loanProduct.getAccountBalance() != null)
                .collect(Collectors.toMap(LoanProductHistoryBillVO::getLoanProductId, LoanProductHistoryBillVO::getAccountBalance));

        // 将结余价格赋值给对应的计划项
        listLoanProductPlanList.forEach(item ->{
            BigDecimal accountBalance = surplusMap.get(item.getLoanProductId());
            if (accountBalance != null) {
                item.setAccountBalance(accountBalance);
            }
        });

        // 账单按计划id分组
        Map<Long, List<LoanProductBillVO>> groupMap = listLoanProductBill.stream()
                .filter(bill -> bill.getLoanProductPlanId() != null)
                .collect(Collectors.groupingBy(LoanProductBillVO::getLoanProductPlanId));

        listLoanProductPlanList.forEach(plan -> {
            // 在分组中获取当前计划的账单
            List<LoanProductBillVO> currentBill = groupMap.get(plan.getLoanProductPlayId());
            if (ValidParam.isNotEmpty(currentBill)) {
                currentBill.forEach(bill -> {
                    // 机构计划
                    if (Objects.equals(bill.getType(), BillTypeEnum.ORG_PLAN.getValue())) {
                        plan.addTotal(bill.getTotal());
                        plan.addAmount(bill.getAmount());
                        plan.addNormal(bill.getTotal());
                        // plan.addWake(bill.getTotal());
                    }
                    // 平台计划
                    if (Objects.equals(bill.getType(), BillTypeEnum.PLATFORM_PLAN.getValue())) {
                        plan.addTotal(bill.getTotal());
                        plan.addAmount(bill.getAmount());
                        plan.addNormal(bill.getTotal());
                        // plan.addWake(bill.getTotal());
                    }
                    // 唤醒计划
                    if (Objects.equals(bill.getType(), BillTypeEnum.WAKE.getValue())) {
                        plan.addTotal(bill.getTotal());
                        plan.addAmount(bill.getAmount());
                        // plan.addNormal(bill.getTotal());
                        plan.addWake(bill.getTotal());
                    }
                });
            }
        });

        // 转换为ApiKeyGroupingWordsVO列表
        List<LoanProductHistoryBillVO> loanProductIdMapList =listLoanProductPlanList.stream()
                .filter(loanProduct -> loanProduct.getLoanProductId() != null)
                .collect(Collectors.groupingBy(LoanProductHistoryBillVO::getLoanProductId))
                .entrySet().stream()
                .map(entry -> {
                    LoanProductHistoryBillVO groupingWordsVO = new LoanProductHistoryBillVO();
                    groupingWordsVO.setLoanProductId(entry.getKey());
                    groupingWordsVO.setChildren(entry.getValue());
                    entry.getValue().forEach(apiKey ->{
                        groupingWordsVO.setGroupingWords(apiKey.getGroupingWords());
                        groupingWordsVO.setName(apiKey.getName());
                        groupingWordsVO.setBalance(apiKey.getBalance());
                        groupingWordsVO.setAccountBalance(apiKey.getAccountBalance());
                        groupingWordsVO.addTotal(apiKey.getTotal());
                        groupingWordsVO.addAmount(apiKey.getAmount());
                        groupingWordsVO.addNormal(apiKey.getNormal());
                        groupingWordsVO.addWake(apiKey.getWake());
                    });
                    return groupingWordsVO;
                })
                .collect(Collectors.toList());

        loanProductIdMapList.forEach(item -> {
            // 空值处理
            if (item.getAmount() == null) {
                item.setAmount(BigDecimal.ZERO);
            }
            // 机构总消耗
            BigDecimal loanProductConsume = item.getAmount();
            // 渠道总消耗
            BigDecimal apiConsume = apiConsumeMap.getOrDefault(item.getLoanProductId(), BigDecimal.ZERO);
            // 机构总充值
            BigDecimal loanProductRecharge = rechargeMap.getOrDefault(item.getLoanProductId(), BigDecimal.ZERO);
            // 机构总补单
            BigDecimal loanProductSupplement = supplementMap.getOrDefault(item.getLoanProductId(), BigDecimal.ZERO);
            // 利润 = 机构总消耗-机构总补单-渠道总消耗
            BigDecimal profit = loanProductConsume.subtract(loanProductSupplement).subtract(apiConsume);

            item.addRecharge(loanProductRecharge);
            item.addSupplement(loanProductSupplement);
            item.setProfit(profit);
        });

        // 转换为ApiKeyGroupingWordsVO列表
        List<LoanProductHistoryBillVO> result = loanProductIdMapList.stream()
                .filter(loanProduct -> loanProduct.getGroupingWords() != null)
                .collect(Collectors.groupingBy(LoanProductHistoryBillVO::getGroupingWords))
                .entrySet().stream()
                .map(entry -> {
                    LoanProductHistoryBillVO groupingWordsVO = new LoanProductHistoryBillVO();
                    groupingWordsVO.setGroupingWords(entry.getKey());
                    groupingWordsVO.setChildren(entry.getValue());
                    entry.getValue().forEach(apiKey ->{
                        groupingWordsVO.addBalance(apiKey.getBalance());
                        groupingWordsVO.addAccountBalance(apiKey.getAccountBalance());
                        groupingWordsVO.addTotal(apiKey.getTotal());
                        groupingWordsVO.addAmount(apiKey.getAmount());
                        groupingWordsVO.addRecharge(apiKey.getRecharge());
                        groupingWordsVO.addSupplement(apiKey.getSupplement());
                        groupingWordsVO.addProfit(apiKey.getProfit());
                        groupingWordsVO.addNormal(apiKey.getNormal());
                        groupingWordsVO.addWake(apiKey.getWake());
                    });
                    return groupingWordsVO;
                })
                .collect(Collectors.toList());

        AtomicLong index = new AtomicLong(1l);
        result.forEach(item -> {
            item.setId(index.getAndIncrement());
            item.getChildren().forEach(item2 ->{
                item2.setId(index.getAndIncrement());
                item2.getChildren().forEach(item3 ->{
                    item3.setId(index.getAndIncrement());
                });
            });
        });

        //  排序
        Map<String, Comparator<LoanProductHistoryBillVO>> comparatorMap = MapUtils.newLinkedHashMap(map -> {
            //  降序
            map.put("total", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getTotal)));
            map.put("amount", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getAmount)));
            map.put("wake", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getWake)));
            map.put("normal", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getNormal)));
            map.put("recharge", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getRecharge)));
            map.put("supplement", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getSupplement)));
            map.put("profit", Comparator.nullsFirst(Comparator.comparing(LoanProductHistoryBillVO::getProfit)));
        });
        Comparator<LoanProductHistoryBillVO> comparator = comparatorMap.get(loanProductHistoryBillQO.getSortField());
        if (comparator == null) {
            comparator = comparatorMap.get("total");
        }
        if (!Eq.str(loanProductHistoryBillQO.getSort(), "ascending")) {
            comparator = comparator.reversed();
        }

        Comparator<LoanProductHistoryBillVO> comparator2 = comparator;
        // 将数据进行排序
        result.sort(comparator2);
        result.forEach(item -> {
            item.getChildren().sort(comparator2);
            item.getChildren().forEach(item2 -> {
                item2.getChildren().sort(comparator2);
            });
        });

        //  通一设置截止时间
        result.forEach(item -> {
            item.setDateTime(displayDateTime);
            item.getChildren().forEach(item2 ->{
                item2.setDateTime(displayDateTime);
                item2.getChildren().forEach(item3 ->{
                    item3.setDateTime(displayDateTime);
                });
            });
        });

        //  通一设置界面中每一级所展示的数据
        result.forEach(item -> {
            item.getChildren().forEach(item2 ->{
                item2.setGroupingWords(null);
                item2.getChildren().forEach(item3 ->{
                    item3.setGroupingWords(null);
                    item3.setName(null);
                    item3.setBalance(null);
                    item3.setAccountBalance(null);
                    item3.setProfit(null);
                });
            });
        });

        //  补单
        boolean supplement = permissionService.hasPermi("product:loanProductHistoryBill:showColumn:supplement");
        //  充值
        boolean recharge = permissionService.hasPermi("product:loanProductHistoryBill:showColumn:recharge");
        //  利润
        boolean profit = permissionService.hasPermi("product:loanProductHistoryBill:showColumn:profit");
        //  正常量
        boolean normal = permissionService.hasPermi("product:loanProductHistoryBill:showColumn:normal");
        //  唤醒量
        boolean wake = permissionService.hasPermi("product:loanProductHistoryBill:showColumn:wake");

        result.forEach(item -> {
            // 根据权限判断是否清空字段
            if (!supplement) item.setSupplement(null);
            if (!recharge) item.setRecharge(null);
            if (!profit) item.setProfit(null);
            if (!normal) item.setNormal(null);
            if (!wake) item.setWake(null);
            item.getChildren().forEach(item2 ->{
                // 根据权限判断是否清空字段
                if (!supplement) item2.setSupplement(null);
                if (!recharge) item2.setRecharge(null);
                if (!profit) item2.setProfit(null);
                if (!normal) item2.setNormal(null);
                if (!wake) item2.setWake(null);
                item2.getChildren().forEach(item3 ->{
                    // 根据权限判断是否清空字段
                    if (!supplement) item3.setSupplement(null);
                    if (!recharge) item3.setRecharge(null);
                    if (!profit) item3.setProfit(null);
                    if (!normal) item3.setNormal(null);
                    if (!wake) item3.setWake(null);
                });
            });
        });

        return result;
    }
}
